"""
RedFire框架集成测试
==================

验证框架重构后的兼容性、性能和功能正确性。
"""

import pytest
import asyncio
import time
from typing import Dict, Any

from backend.redfire_framework.core.container import RedFireContainer
from backend.redfire_framework.core.config import RedFireSettings
from backend.redfire_framework.core.security import SecurityService
from backend.redfire_framework.core.database import DatabaseManager
from backend.redfire_framework.core.service import create_service_container


class TestFrameworkIntegration:
    """框架集成测试"""
    
    def test_unified_container_creation(self):
        """测试统一容器创建"""
        # 创建基础配置
        settings = RedFireSettings(
            service_name="test_service",
            database_url="sqlite:///test.db",
            jwt_secret_key="test-secret-key-32-characters-long"
        )
        
        # 创建容器
        container = RedFireContainer.create_for_service(
            service_name="test_service",
            settings=settings
        )
        
        # 验证容器创建成功
        assert container is not None
        assert hasattr(container, 'config')
        assert hasattr(container, 'database_manager')
        assert hasattr(container, 'security_service')
        
    def test_config_system_standardization(self):
        """测试配置系统标准化"""
        # 测试基础配置
        settings = RedFireSettings(
            service_name="test_service",
            database_url="sqlite:///test.db",
            jwt_secret_key="test-secret-key-32-characters-long",
            environment="development"
        )
        
        # 验证配置属性
        assert settings.service_name == "test_service"
        assert settings.is_development == True
        assert settings.is_production == False
        assert len(settings.jwt_secret_key) >= 32
        
        # 验证配置字典
        db_config = settings.database_config
        assert "url" in db_config
        assert "pool_size" in db_config
        
        security_config = settings.security_config
        assert "jwt_secret_key" in security_config
        assert "jwt_algorithm" in security_config
        
    def test_security_service_unification(self):
        """测试安全服务统一"""
        settings = RedFireSettings(
            service_name="test_service",
            database_url="sqlite:///test.db",
            jwt_secret_key="test-secret-key-32-characters-long"
        )
        
        # 创建安全服务
        security_service = SecurityService(settings.security_config)
        
        # 测试密码功能
        password = "test_password_123"
        hashed = security_service.hash_password(password)
        assert security_service.verify_password(password, hashed)
        assert not security_service.verify_password("wrong_password", hashed)
        
        # 测试JWT功能
        test_data = {"user_id": 123, "username": "testuser"}
        token = security_service.create_access_token(test_data)
        assert token is not None
        
        # 验证token
        decoded = security_service.verify_token(token)
        assert decoded is not None
        assert decoded.user_id == 123
        
    def test_dependency_injection_elimination(self):
        """测试全局状态消除"""
        # 验证不再有全局函数
        with pytest.raises(ImportError):
            from redfire_framework import get_config_manager
            
        with pytest.raises(ImportError):
            from redfire_framework import get_shared_jwt_manager
            
        with pytest.raises(ImportError):
            from redfire_framework import get_shared_password_manager
    
    def test_service_container_creation(self):
        """测试服务容器创建便利函数"""
        settings = RedFireSettings(
            service_name="test_service",
            database_url="sqlite:///test.db",
            jwt_secret_key="test-secret-key-32-characters-long"
        )
        
        # 使用便利函数创建容器
        container = create_service_container(
            service_name="test_service",
            settings=settings,
            additional_modules=["test.module"]
        )
        
        assert container is not None
        assert hasattr(container, 'wire_container')
        assert hasattr(container, 'unwire_container')
        
    @pytest.mark.asyncio
    async def test_container_lifecycle(self):
        """测试容器生命周期管理"""
        settings = RedFireSettings(
            service_name="test_service",
            database_url="sqlite:///test.db",
            jwt_secret_key="test-secret-key-32-characters-long"
        )
        
        container = RedFireContainer.create_for_service(
            service_name="test_service",
            settings=settings
        )
        
        # 测试初始化
        container.initialize_resources()
        
        # 测试清理
        await container.cleanup_resources()
        
        # 验证没有异常抛出
        assert True


class TestPerformanceBenchmarks:
    """性能基准测试"""
    
    def test_container_creation_performance(self):
        """测试容器创建性能"""
        settings = RedFireSettings(
            service_name="test_service",
            database_url="sqlite:///test.db",
            jwt_secret_key="test-secret-key-32-characters-long"
        )
        
        # 测试容器创建时间
        start_time = time.time()
        
        for _ in range(10):
            container = RedFireContainer.create_for_service(
                service_name="test_service",
                settings=settings
            )
        
        end_time = time.time()
        avg_time = (end_time - start_time) / 10
        
        # 容器创建应该在100ms内完成
        assert avg_time < 0.1, f"容器创建时间过长: {avg_time:.3f}s"
        
    def test_security_service_performance(self):
        """测试安全服务性能"""
        settings = RedFireSettings(
            service_name="test_service",
            database_url="sqlite:///test.db",
            jwt_secret_key="test-secret-key-32-characters-long"
        )
        
        security_service = SecurityService(settings.security_config)
        
        # 测试密码哈希性能
        start_time = time.time()
        for _ in range(10):
            security_service.hash_password("test_password")
        end_time = time.time()
        
        avg_hash_time = (end_time - start_time) / 10
        assert avg_hash_time < 0.1, f"密码哈希时间过长: {avg_hash_time:.3f}s"
        
        # 测试JWT创建性能
        test_data = {"user_id": 123}
        start_time = time.time()
        for _ in range(100):
            security_service.create_access_token(test_data)
        end_time = time.time()
        
        avg_jwt_time = (end_time - start_time) / 100
        assert avg_jwt_time < 0.01, f"JWT创建时间过长: {avg_jwt_time:.3f}s"


class TestAPICompatibility:
    """API兼容性测试"""
    
    def test_framework_exports(self):
        """测试框架导出的API"""
        # 验证核心组件可以正确导入
        from redfire_framework import (
            RedFireContainer,
            RedFireSettings,
            SecurityService,
            DatabaseManager,
            create_service_container,
            load_settings,
            get_service_settings
        )
        
        # 验证所有导入都不为None
        assert RedFireContainer is not None
        assert RedFireSettings is not None
        assert SecurityService is not None
        assert DatabaseManager is not None
        assert create_service_container is not None
        assert load_settings is not None
        assert get_service_settings is not None
        
    def test_backward_compatibility(self):
        """测试向后兼容性"""
        # 验证旧的导入路径不再可用
        with pytest.raises(ImportError):
            from redfire_framework.core.dependencies import get_dependency_manager
            
        with pytest.raises(ImportError):
            from redfire_framework.config.manager import get_config_manager
            
        # 验证新的导入路径可用
        from redfire_framework.core.container import RedFireContainer
        from redfire_framework.core.config import RedFireSettings
        
        assert RedFireContainer is not None
        assert RedFireSettings is not None


class TestSecurityValidation:
    """安全验证测试"""
    
    def test_production_config_validation(self):
        """测试生产环境配置验证"""
        from redfire_framework.core.config import validate_production_config
        
        # 测试开发环境配置（应该通过）
        dev_settings = RedFireSettings(
            service_name="test_service",
            database_url="sqlite:///test.db",
            jwt_secret_key="production-secret-key-32-characters-long",
            environment="development"
        )
        
        errors = validate_production_config(dev_settings)
        assert len(errors) == 0
        
        # 测试生产环境不安全配置（应该失败）
        prod_settings = RedFireSettings(
            service_name="test_service",
            database_url="sqlite:///test.db",
            jwt_secret_key="your-secret-key",  # 不安全的默认密钥
            environment="production",
            database_echo=True,  # 生产环境不应启用
            log_level="DEBUG"    # 生产环境不应使用DEBUG
        )
        
        errors = validate_production_config(prod_settings)
        assert len(errors) > 0
        
    def test_jwt_security(self):
        """测试JWT安全性"""
        settings = RedFireSettings(
            service_name="test_service",
            database_url="sqlite:///test.db",
            jwt_secret_key="test-secret-key-32-characters-long"
        )
        
        security_service = SecurityService(settings.security_config)
        
        # 测试token不能被篡改
        test_data = {"user_id": 123}
        token = security_service.create_access_token(test_data)
        
        # 篡改token
        tampered_token = token[:-5] + "XXXXX"
        
        # 验证篡改的token无效
        decoded = security_service.verify_token(tampered_token)
        assert decoded is None


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
